<?php
// +----------------------------------------------------------------------
// | ZGUAN [ 致力于帮助更多的中小企业实现低成本数字化转型 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.zguan.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ZGUAN 并不是自由软件，未经许可不能去掉ZGUAN 相关版权
// +----------------------------------------------------------------------
// | Author: ZGUAN Team <admin@zguan.cn>  0769-82282996  15899929162
// +----------------------------------------------------------------------
namespace app\controller\property\energy;

use think\App;
use app\controller\property\Base;
use app\validate\energy\EnergyMeterValidate;
use app\validate\energy\EnergyMeterDayValidate;
use app\common\repositories\energy\EnergyPlanRepository;
use app\common\repositories\energy\EnergyMeterRepository;
use app\common\repositories\energy\EnergyMeterDayRepository;
use app\common\repositories\energy\EnergyMeterLogRepository;
use app\common\repositories\energy\EnergyBalanceLogRepository;
use app\common\repositories\energy\EnergyOperateLogRepository;
use app\common\repositories\property\basic\PropertyBasicRepository;


class EnergyMeter extends Base
{
    protected $repository;

    public function __construct(App $app, EnergyMeterRepository $repository)
    {
        parent::__construct($app);
        $this->repository = $repository;
        $this->assign([
            'addAuth' => property_auth('propertyEnergyMeterAdd'),
            'editAuth' => property_auth('propertyEnergyMeterEdit'),
            'delAuth' => property_auth('propertyEnergyMeterDel'),
            'detailAuth' => property_auth('propertyEnergyMeterDetail'),
        ]);
    }

    protected function commonParams()
    {
        /** @var PropertyBasicRepository $propertyBasicRepository */
        $propertyBasicRepository = app()->make(PropertyBasicRepository::class);
        $propertyData = $propertyBasicRepository->getUserAllPropertyList($this->request->userId);
        $energyTypeData = $this->repository::ENERGY_TYPE;
        $this->assign([
            'propertyData' => $propertyData,
            'energyTypeData' => $energyTypeData,
        ]);
    }

    public function list()
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'property_id' => '',
                'room_id' => '',
                'keywords' => '',
            ]);
            [$page, $limit] = $this->getPage();
            $data = $this->repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $data['list'], 'count' => $data['count']]);
        }
        $this->commonParams();
        return $this->fetch('energy/meter/list');
    }

    public function add()
    {
        if ($this->request->isAjax() && $this->request->isGet() && $this->request->param('get_type') == 'planData') {
            $propertyId = $this->request->param('property_id');
            /** @var EnergyPlanRepository $planRepository */
            $planRepository = app()->make(EnergyPlanRepository::class);
            $planData = $planRepository->getSearch([])
                ->where('property_id', $propertyId)
                ->field('id,plan_name')
                ->select()->toArray();
            return json()->data(['code' => 0, 'data' => $planData]);
        } else if ($this->request->isPost()) {
            $param = $this->request->param([
                'property_id' => '',
                'plan_id' => '',
                'is_public' => '',
                'wit_type' => '',
                'plan_type' => '',
                'energy_type' => '',
                'energy_no' => '',
                'energy_name' => '',
                'off_type' => '',
                'off_time' => '',
                'unit_price' => '',
                'beilv' => '',
                'remark' => '',
            ]);
            validate(EnergyMeterValidate::class)->scene('add')->check($param);
            if ($this->repository->fieldExists('energy_no', $param['energy_no'])) {
                return $this->error(' 设备编号 ' . $param['energy_no'] . ' 己存在');
            }
            if ($param['plan_id'] > 0) {
                $param['unit_price'] = '0.00';
            } else if ($param['unit_price'] > 0) {
                $param['plan_id'] = 0;
            }
            try {
                $res = $this->repository->addInfo($param, $this->request->propertyId, $this->request->userId);
                if ($res) {
                    return $this->success('添加成功');
                } else {
                    return $this->error('添加失败');
                }
            } catch (\Exception $e) {
                exception_log('添加能源失败', $e);
                return $this->error('网络错误');
            }
        } else {
            $this->commonParams();
            return $this->fetch('energy/meter/add');
        }

    }


    public function edit()
    {
        $id = (int)$this->request->param('id');
        if (!$id) {
            return $this->error('参数错误');
        }
        $info = $this->repository->get($id);
        if (!$info) {
            return $this->error('信息错误');
        }
        if ($this->request->isPost()) {
            $param = $this->request->param([
                'plan_id' => '',
                'is_public' => '',
                'wit_type' => '',
                'plan_type' => '',
                'energy_type' => '',
                'energy_no' => '',
                'energy_name' => '',
                'off_type' => '',
                'off_time' => '',
                'beilv' => '',
                'unit_price' => '',
                'remark' => '',
            ]);
            validate(EnergyMeterValidate::class)->scene('edit')->check($param);
            if ($this->repository->propertyFieldExists($this->request->propertyId, 'energy_no', $param['energy_no'], $id)) {
                return $this->error(' 设备编号 ' . $param['energy_no'] . ' 己存在');
            }
            if ($param['plan_id'] > 0) {
                $param['unit_price'] = '0.00';
            } else if ($param['unit_price'] > 0) {
                $param['plan_id'] = 0;
            }
            try {
                $res = $this->repository->editInfo($info, $param, $this->request->userId);
                if ($res) {
                    return $this->success('修改成功');
                } else {
                    return $this->error('修改失败');
                }
            } catch (\Exception $e) {
                exception_log('编辑能源失败', $e);
                return $this->error('网络错误');
            }
        } else {
            /** @var EnergyPlanRepository $planRepository */
            $planRepository = app()->make(EnergyPlanRepository::class);
            $planData = $planRepository->getSearch([])
                ->where('property_id', $info['property_id'])
                ->field('id,plan_name')
                ->select()->toArray();
            $this->commonParams();
            return $this->fetch('energy/meter/edit', [
                'info' => $info,
                'planData' => $planData,
            ]);
        }
    }


    public function detail(EnergyMeterDayRepository $repository)
    {
        $energyId = (int)$this->request->param('energy_id');
        if ($energyId <= 0) {
            return $this->error('参数错误');
        }
        $meterInfo = $this->repository->getDetail($energyId);
        if ($meterInfo['id'] <= 0) {
            return $this->error('设备不存在');
        }
        if ($this->request->isAjax()) {
            $param = $this->request->param([
                'time' => ''
            ]);
            $res = $repository->getEnergyMeterDayList($energyId, $param);
            return json()->data(['code' => 0, 'data' => $res]);
        } else {
            return $this->fetch('energy/meter/detail', [
                'meterInfo' => $meterInfo,
                'copyReadMeterAuth' => property_auth('propertyEnergyMeterDayManuallyCopy'),
                'readMeterAuth' => property_auth('propertyEnergyMeterAutoReadCopy'),
                'onMeterAuth' => property_auth('propertyEnergyMeterOn'),
                'offMeterAuth' => property_auth('propertyEnergyMeterOff'),
                'updateMeterAuth' => property_auth('propertyEnergyMeterUpdateOnOff'),
            ]);
        }
    }


    public function del()
    {
        $ids = (array)$this->request->param('ids');
        try {
            $data = $this->repository->batchDelete($ids, $this->request->userId);
            if ($data) {
                return $this->success('删除成功');
            } else {
                return $this->error('删除失败');
            }
        } catch (\Exception $e) {
            exception_log('删除能源失败', $e);
            return $this->error('网络失败');
        }
    }


    /**
     * 日用电量抄读 人工
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-04-10 09:06
     */
    public function dayManuallyCopy()
    {
        $energyId = (int)$this->request->param('energy_id');
        if (!$energyId) {
            return $this->error('参数错误');
        }
        $meterInfo = $this->repository->getDetail($energyId);
        if ($meterInfo['unit_price'] <= 0 && $meterInfo['plan_id'] <= 0) {
            return $this->error('请先设置收费方案');
        }
        if ($this->request->isPost()) {
            $param = $this->request->param([
                'day_time' => '',
                'read_z' => '',
                'read_j' => '',
                'read_f' => '',
                'read_p' => '',
                'read_g' => '',
            ]);
            $param['day_time'] = $param['day_time'] ?: date('Y-m-d');
            if ($meterInfo['read_time'] > date('Y-m-d')) {
                return $this->error('每日限抄读一次');
            }
            validate(EnergyMeterDayValidate::class)->scene('add')->check($param);
            if ($meterInfo['mode_type'] == 2) {
                if ($param['read_j'] <= $meterInfo['read_j']) {
                    return $this->error('尖时 用量读数必须大于上期读数');
                }
                if ($param['read_f'] <= $meterInfo['read_f']) {
                    return $this->error('谷时 用量读数必须大于上期读数');
                }
                if ($param['read_p'] <= $meterInfo['read_p']) {
                    return $this->error('平时 用量读数必须大于上期读数');
                }
                if ($param['read_g'] <= $meterInfo['read_g']) {
                    return $this->error('谷时 用量读数必须大于上期读数');
                }
                $param['read_z'] = bcadd($param['read_j'], $param['read_f'], 2);
                $param['read_z'] = bcadd($param['read_z'], $param['read_p'], 2);
                $param['read_z'] = bcadd($param['read_z'], $param['read_g'], 2);
            } else {
                if ($param['read_z'] <= $meterInfo['read_z']) {
                    return $this->error('本期 用量读数必须大于上期读数');
                }
            }
            try {
                $this->repository->manuallyMeterReading($meterInfo, $param, $this->request->userId);
                return $this->success('抄读成功');
            } catch (\Exception $e) {
                exception_log('人工抄读失败', $e);
                return $this->error('网络错误');
            }
        } else {
            return $this->fetch('energy/meter/day_copy_read', [
                'meterInfo' => $meterInfo
            ]);
        }
    }

    /**
     * 设备日志
     * @param EnergyMeterLogRepository $repository
     * @return \think\response\Json|void
     *
     * @author Amos
     * 2024-05-09 21:54
     */
    public function meterLog(EnergyMeterLogRepository $repository)
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'energy_id' => ''
            ]);
            [$page, $limit] = $this->getPage();
            $res = $repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $res['list'], 'count' => $res['count']]);
        }
    }

    /**
     * 设备充值
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-05-09 21:54
     */
    public function recharge()
    {
        $id = (int)$this->request->param('id');
        if (!$id) {
            return $this->error('参数错误');
        }
        $info = $this->repository->get($id);
        if (!$info) {
            return $this->error('信息错误');
        }
        if ($info['plan_type'] == 1) {
            return $this->error('后付费不支持充值');
        }
        if ($this->request->isPost()) {
            $param = $this->request->param([
                'pay_method' => '',
                'is_type' => '',
                'pay_amount' => '',
                'remark' => '',
            ]);
            $param['pay_type'] = 2;
            validate(EnergyMeterValidate::class)->scene('recharge')->check($param);
            try {
                $res = $this->repository->rechargeInfo($info['id'], $param, $this->request->userId);
                if ($res) {
                    return $this->success('充值成功');
                } else {
                    return $this->error('充值失败');
                }
            } catch (\Exception $e) {
                exception_log('设备充值失败', $e);
                return $this->error('网络错误');
            }
        } else {
            return $this->fetch('energy/prepay/recharge', [
                'info' => $info,
            ]);
        }
    }

    /**
     * 批量充值
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-03-15 21:02
     */
    public function rechargeBatch()
    {
        if ($this->request->isPost()) {
            $param = $this->request->param([
                'id' => '',
                'pay_method' => '',
                'is_type' => '',
                'pay_amount' => '',
                'remark' => '',
            ]);
            $param['pay_type'] = 2;
            $param['remark'] = $param['remark'] . '批量充值';
            validate(EnergyMeterValidate::class)->scene('recharge')->check($param);
            $ids = array_filter(explode(',', $param['id']));
            $num = 0;
            foreach ($ids as $v) {
                $info = $this->repository->getSearch([])->where('id', $v)
                    ->where('plan_type', 'in', '2,3')
                    ->field('id,energy_no,energy_name,energy_type,plan_type,balance,read_time')
                    ->find();
                if (isset($info) && $info['id'] > 0 && ($info['plan_type'] == 2 || $info['status'] == 3)) {
                    $res = $this->repository->rechargeInfo($info['id'], $param, $this->request->userId);
                    if ($res) {
                        $num++;
                    }
                }
            }
            if ($num) {
                return $this->success('成功充值 ' . $num . ' 台设备');
            } else {
                return $this->error('设备充值失败');
            }
        } else {
            $id = $this->request->param('id');
            $ids = array_filter(explode(',', $id));
            $rechargelist = $this->repository->getSearch([])
                ->where('id', 'in', $ids)
                ->where('plan_type', 'in', '2,3')
                ->field('id,energy_no,energy_name,energy_type,plan_type,balance,read_time')
                ->select()->toArray();
            $this->assign([
                'rechargeData' => $rechargelist,
            ]);
            return $this->fetch('energy/prepay/recharge_batch');
        }
    }

    /**
     * 设备余额变动日志
     * @param EnergyBalanceLogRepository $repository
     * @return \think\response\Json|void
     *
     * @author Amos
     * 2024-05-18 22:00
     */
    public function balanceLog(EnergyBalanceLogRepository $repository)
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'energy_id' => ''
            ]);
            [$page, $limit] = $this->getPage();
            $res = $repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $res['list'], 'count' => $res['count']]);
        }
    }

    /**
     * 删除设备日志
     * @param EnergyMeterLogRepository $repository
     * @return string|\think\response\Json|\think\response\View
     *
     * @author Amos
     * 2024-05-18 21:59
     */
    public function delMeterLog(EnergyMeterLogRepository $repository)
    {
        $ids = (array)$this->request->param('ids');
        try {
            $data = $repository->batchDelete($ids);
            if ($data) {
                return $this->success('删除成功');
            } else {
                return $this->error('删除失败');
            }
        } catch (\Exception $e) {
            exception_log('删除能源日志失败', $e);
            return $this->error('网络失败');
        }
    }

    /**
     *  设备操作日志
     * @param EnergyOperateLogRepository $repository
     * @return \think\response\Json|void
     *
     * @author Amos
     * 2024-05-18 22:07
     */
    public function operateLog(EnergyOperateLogRepository $repository)
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'energy_id' => ''
            ]);
            [$page, $limit] = $this->getPage();
            $res = $repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $res['list'], 'count' => $res['count']]);
        }
    }


    public function delOperateLog(EnergyOperateLogRepository $repository)
    {
        $ids = (array)$this->request->param('ids');
        try {
            $data = $repository->batchDelete($ids);
            if ($data) {
                return $this->success('删除成功');
            } else {
                return $this->error('删除失败');
            }
        } catch (\Exception $e) {
            exception_log('删除能源操作日志失败', $e);
            return $this->error('网络失败');
        }
    }

    /**
     * 日用量列表
     * @param EnergyMeterDayRepository $repository
     * @return \think\response\Json|void
     *
     * @author Amos
     * 2024-05-18 21:51
     */
    public function dayMeterList(EnergyMeterDayRepository $repository)
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'energy_id' => ''
            ]);
            [$page, $limit] = $this->getPage();
            $res = $repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $res['list'], 'count' => $res['count']]);
        }
    }


    /**
     * 实时抄读
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-04-10 11:16
     */
    public function autoReadCopy()
    {
        $param = $this->request->param(['id' => '', 'type' => '', 'remark' => '',]);
        if ($param['id'] <= 0) {
            return $this->error('参数错误');
        }
        if ($param['remark'] == '') {
            return $this->error('请输入备注说明');
        }
        if (!$this->repository->propertyExists($this->request->propertyId, $param['id'])) {
            return $this->error('数据不存在');
        }
        $meterInfo = $this->repository->get($param['id']);
        if ($meterInfo['wit_type'] != 1) {
            return $this->error('非智能表不支持此操作');
        }
        $res = $this->repository->autoReadCopy($meterInfo, $param, $this->request->userId);
        return json()->data(['code' => 0, 'data' => $res]);
    }

    /**
     * 状态更新
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-05-18 21:43
     */
    public function updateOnOff()
    {
        $param = $this->request->param(['id' => '', 'type' => '', 'remark' => '',]);
        if ($param['id'] <= 0) {
            return $this->error('参数错误');
        }
        if ($param['remark'] == '') {
            return $this->error('请输入备注说明');
        }
        if (!$this->repository->propertyExists($this->request->propertyId, $param['id'])) {
            return $this->error('数据不存在');
        }
        $meterInfo = $this->repository->get($param['id']);
        if ($meterInfo['wit_type'] != 1) {
            return $this->error('非智能表不支持此操作');
        }
        $res = $this->repository->updateOnOff($meterInfo, $param, $this->request->userId);
        return json()->data(['code' => 0, 'data' => $res]);
    }


    /**
     * 拉闸
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-04-10 15:50
     */
    public function offEnergyMeter()
    {
        $param = $this->request->param(['id' => '', 'type' => '', 'remark' => '',]);
        if ($param['id'] <= 0) {
            return $this->error('参数错误');
        }
        if ($param['remark'] == '') {
            return $this->error('请输入备注说明');
        }
        if (!$this->repository->propertyExists($this->request->propertyId, $param['id'])) {
            return $this->error('数据不存在');
        }
        $meterInfo = $this->repository->get($param['id']);
        if ($meterInfo['wit_type'] != 1) {
            return $this->error('非智能设备不支持此操作');
        }
        $res = $this->repository->offEnergyMeter($meterInfo, $param, $this->request->userId);
        return json()->data(['code' => 0, 'data' => $res]);
    }

    /**
     * 合闸
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-04-10 15:50
     */
    public function onEnergyMeter()
    {
        $param = $this->request->param(['id' => '', 'type' => '', 'remark' => '',]);
        if ($param['id'] <= 0) {
            return $this->error('参数错误');
        }
        if ($param['remark'] == '') {
            return $this->error('请输入备注说明');
        }
        if (!$this->repository->propertyExists($this->request->propertyId, $param['id'])) {
            return $this->error('数据不存在');
        }
        $meterInfo = $this->repository->get($param['id']);
        if ($meterInfo['wit_type'] != 1) {
            return $this->error('非智能设备不支持此操作');
        }
        $res = $this->repository->onEnergyMeter($meterInfo, $param, $this->request->userId);
        return json()->data(['code' => 0, 'data' => $res]);
    }


    /**
     * 结果回调
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryOperateResult()
    {
        $requestId = $this->request->param('request_id');
        if (!$requestId) {
            return $this->error('参数错误');
        }
        /** @var EnergyOperateLogRepository $operateLogRepository */
        $operateLogRepository = app()->make(EnergyOperateLogRepository::class);
        $info = $operateLogRepository->getSearch([])
            ->where('request_id', $requestId)
            ->find();
        if (!$info) {
            return $this->error('数据不存在');
        }
        return json()->data(['code' => 0, 'data' => $info]);
    }


    /**
     * 预付费设备列表
     * @return string|\think\response\Json
     * @throws \Exception
     *
     * @author Amos
     * 2024-05-18 21:49
     */
    public function prepayList()
    {
        if ($this->request->isAjax()) {
            $where = $this->request->param([
                'property_id' => '',
                'room_id' => '',
                'keywords' => '',
            ]);
            $where['plan_type'] = [2, 3];
            [$page, $limit] = $this->getPage();
            $data = $this->repository->getpropertyList($where, $page, $limit, $this->request->propertyId);
            return json()->data(['code' => 0, 'data' => $data['list'], 'count' => $data['count']]);
        }
        $this->commonParams();
        return $this->fetch('energy/prepay/list', [
            'usersAddAuth' => property_auth('propertyEnergyUsersAdd'),
            'rechargeAuth' => property_auth('propertyEnergyMeterRecharge'),
            'rechargeBatchAuth' => property_auth('propertyEnergyMeterRechargeBatch'),
        ]);
    }


}